#include "adc.h"
#include "includes.h"
#include "delay.h"

/**
 @brief ADC1火焰传感器初始化
*/
void adc1_init(void)
{
	GPIO_InitTypeDef  	  	GPIO_InitStructure;
	ADC_InitTypeDef       	ADC_InitStructure;
	ADC_CommonInitTypeDef 	ADC_CommonInitStructure;
	
	//端口A的硬件时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);  
	
	//ADC1的硬件时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
	
	//配置PA2引脚为AN（模拟信号）模式
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_6; 	//2号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;//模拟模式
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOA,&GPIO_InitStructure);	


	//配置ADC1相关参数
	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;	//单个ADC工作
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;	//ADC1的硬件时钟频率=84MHz/2=42MHz
	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;//DMA关闭
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//5*(1/42MHz)
	ADC_CommonInit(&ADC_CommonInitStructure);	
	
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;		//转换结果为12位的数据
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;				//单通道扫描
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;			//连续工作
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//不需要脉冲触发ADC工作
	//ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;		//转换的结果右对齐存储
	ADC_InitStructure.ADC_NbrOfConversion = 1;					//告诉ADC要扫描的通道数目，当前是1个
	ADC_Init(ADC1, &ADC_InitStructure);
	
	
	//PA2引脚连接到ADC1，通道6序号为1，对采样点的采样时间为3个ADC时钟周期，时间越长越准确
	ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 1, ADC_SampleTime_3Cycles);
	
	//使能ADC1工作
	ADC_Cmd(ADC1, ENABLE);
}


/**
 @brief ADC2可燃气体(烟雾)传感器初始化
*/
void adc2_init(void)
{
	GPIO_InitTypeDef  	  	GPIO_InitStructure;
	ADC_InitTypeDef       	ADC_InitStructure;
	ADC_CommonInitTypeDef 	ADC_CommonInitStructure;
	
	//端口B的硬件时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);
	//ADC1的硬件时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2,ENABLE);
	
	//配置PB0引脚为AN（模拟信号）模式
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_0; 	//2号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_AN;//模拟模式
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻
	GPIO_Init(GPIOB,&GPIO_InitStructure);
	
	//配置ADC2相关参数
	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;	//单个ADC工作
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;	//ADC2的硬件时钟频率=84MHz/2=42MHz
	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;//DMA关闭
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//5*(1/42MHz)
	ADC_CommonInit(&ADC_CommonInitStructure);	
	
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;		//转换结果为12位的数据
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;				//单通道扫描
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;			//连续工作
	ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//不需要脉冲触发ADC工作
	//ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;		//转换的结果右对齐存储
	ADC_InitStructure.ADC_NbrOfConversion = 1;					//告诉ADC要扫描的通道数目，当前是1个
	ADC_Init(ADC2, &ADC_InitStructure);
	
	//PB0引脚连接到ADC2，通道8序号为1，对采样点的采样时间为3个ADC时钟周期，时间越长越准确
	ADC_RegularChannelConfig(ADC2, ADC_Channel_8, 1, ADC_SampleTime_3Cycles);
	
	//使能ADC2工作
	ADC_Cmd(ADC2, ENABLE);
}


/**
 @brief ADC3光敏电阻初始化
*/
void adc3_init(void){
	ADC_CommonInitTypeDef ADC_CommonInitStructure;
	ADC_InitTypeDef       ADC_InitStructure;
	
	//使能ADC的硬件时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3, ENABLE);
	
	//配置ADC相关的参数
	ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent;//只需要一个ADC独立工作
	ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2;//预分频值为2，ADC的硬件时钟=84MHz/2=42MHz
	ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled;//关闭DMA
	ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles;//两个采样点的间隔=5*(1/42MHz)
	ADC_CommonInit(&ADC_CommonInitStructure);
	
	ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;//12位的分辨率(0~4095)
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;//只扫描一个通道
	ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;//连续转换
	//ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
	//ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_CC1;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;//转换得到后的12位数据进行右对齐存储
	ADC_InitStructure.ADC_NbrOfConversion = 1;//转换1个通道
	ADC_Init(ADC3, &ADC_InitStructure);
	
	//配置ADC3的通道5，扫描序号为1，采样时间为3个ADC时钟周期
	ADC_RegularChannelConfig(ADC3, ADC_Channel_5, 1, ADC_SampleTime_3Cycles);
	
	//使能ADC工作
	ADC_Cmd(ADC3, ENABLE);
}


/**
 @brief 初始化光敏传感器,引脚PF7
*/
void lsens_init(void){
	GPIO_InitTypeDef  GPIO_InitStructure;
	//使能端口F的硬件时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
	
	//配置端口F为AN模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
	GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
	GPIO_Init(GPIOF, &GPIO_InitStructure);
}

/**
 @brief 获取一个平滑的光敏电阻数据,该函数需要500ms
*/
uint32_t lsens_get_val(void){
	uint32_t temp_val = 0;
	uint8_t t;

	for(t=0;t<100;t++)
	{
		temp_val += ADC_GetConversionValue(ADC3);
		//读取 ADC 值,通道 5
		delay_ms(5);
	}
	
	temp_val /= 100;//得到平均值
	if(temp_val>4095){
		temp_val = 4095;
	}
	return temp_val;
}

void exit9_init(void)
{
	GPIO_InitTypeDef  	  	GPIO_InitStructure;
	EXTI_InitTypeDef  	  	EXTI_InitStructure;
	NVIC_InitTypeDef 	 	NVIC_InitStructure;
	
	//打开端口B的硬件时钟，就是供电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
	
	//打开SYSCFG硬件时钟，就是供电
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_9;	//9号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;  //输入模式
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速，速度越高，响应越快，但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻(因为外部已经有上拉电阻)
	GPIO_Init(GPIOB,&GPIO_InitStructure);	
	
	//将PB9连接到EXTI3
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource9);

	EXTI_InitStructure.EXTI_Line = EXTI_Line9;	//外部中断9
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断触发
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  //上升沿用于检测火焰的存在。下降沿用于检测火焰的消失。
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;			//使能工作
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;			//外部中断9-5中断号
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY;//中断抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x05;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//打开外部中断0请求通道
	NVIC_Init(&NVIC_InitStructure);

}

void exit1_init(void)
{
	GPIO_InitTypeDef  	  	GPIO_InitStructure;
	EXTI_InitTypeDef  	  	EXTI_InitStructure;
	NVIC_InitTypeDef 	 	NVIC_InitStructure;
	
	//打开端口A的硬件时钟，就是供电
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB,ENABLE);
	
	//打开SYSCFG硬件时钟，就是供电
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin   = GPIO_Pin_1;	//0号引脚
	GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IN;  //输入模式
	GPIO_InitStructure.GPIO_Speed = GPIO_High_Speed;//高速，速度越高，响应越快，但是功耗会更高
	GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;//不使能上下拉电阻(因为外部已经有上拉电阻)
	GPIO_Init(GPIOB,&GPIO_InitStructure);	
	
	//将PB1连接到EXTI1
	SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource1);

	EXTI_InitStructure.EXTI_Line = EXTI_Line1;	//外部中断1
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; //中断触发
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;  //上升沿用于检测是否存在。下降沿用于检测hi否消失。
	EXTI_InitStructure.EXTI_LineCmd = ENABLE;			//使能工作
	EXTI_Init(&EXTI_InitStructure);
	
	NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;			//外部中断1中断号
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY;//中断抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x05;		//响应优先级
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				//打开外部中断0请求通道
	NVIC_Init(&NVIC_InitStructure);

}

/* ADC模块中断 */
void EXTI9_5_IRQHandler(void)
{
	uint32_t ulReturn;
	ulReturn = taskENTER_CRITICAL_FROM_ISR();
	
	if(EXTI_GetITStatus(EXTI_Line9) == SET)
	{
		
		if(PBin(9))
		{
			PFout(10) = 1;
		}
		else
		{
			PFout(10) = 0;
		}
		
		EXTI_ClearITPendingBit(EXTI_Line9);
		
	}
		/* 退出临界段 */
	taskEXIT_CRITICAL_FROM_ISR( ulReturn );
}

void EXTI1_IRQHandler(void)
{
	uint32_t ulReturn;
	ulReturn = taskENTER_CRITICAL_FROM_ISR();
	
	if(EXTI_GetITStatus(EXTI_Line1) == SET)
	{
		
		if(PBin(1))
		{
			PFout(10) = 1;
		}
		else
		{
			PFout(10) = 0;
		}
		
		EXTI_ClearITPendingBit(EXTI_Line1);
		
	}
		/* 退出临界段 */
	taskEXIT_CRITICAL_FROM_ISR( ulReturn );

}
